/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.wdb.domain;

import org.vacoor.nothing.wdb.util.Jdbcs;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import static org.vacoor.nothing.wdb.util.Jdbcs.*;

/**
 */
public class DbSchema {
    final DatabaseMetaData dbMeta;
    final String name;

    public DbSchema(DatabaseMetaData dbMeta, String name) {
        this.dbMeta = dbMeta;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public static DbSchema[] readDbSchemas(DatabaseMetaData dbMeta) throws SQLException {
        List<DbSchema> dbSchemas = new ArrayList<DbSchema>();
        String connSchema = getConnectionSchemaName(dbMeta);

        ResultSet schemas = dbMeta.getSchemas();
        while (schemas.next()) {
            String name = schemas.getString("TABLE_SCHEM");
            boolean isDefault = name.equals(connSchema);
            System.out.println(name + ", default: " + isDefault);
            dbSchemas.add(new DbSchema(dbMeta, name));
        }
        Jdbcs.close(schemas);

        return dbSchemas.toArray(new DbSchema[dbSchemas.size()]);
    }

    public DbTable[] getTables() throws SQLException {
        return getTables((String) null);
    }

    public DbTable[] getTables(String tabName) throws SQLException {
        return getTables(tabName, null);
    }

    public DbTable[] getTables(String[] tabTypes) throws SQLException {
        return getTables(null, tabTypes);
    }

    public DbTable[] getTables(String tabName, String[] tabTypes) throws SQLException {
        return readTables(dbMeta, name, tabName, tabTypes);
    }

    /**
     * { "TABLE", "SYSTEM TABLE", "VIEW", "SYSTEM VIEW", "TABLE LINK", "SYNONYM", "EXTERNAL" };
     */
    DbTable[] readTables(DatabaseMetaData dbMeta, String schema, String tabName, String[] tabTypes) throws SQLException {
        List<DbTable> dbTables = new ArrayList<DbTable>();

        ResultSet tables = dbMeta.getTables(null, schema, tabName, tabTypes);
        while (tables.next()) {
            // tables.getString("TABLE_SCHEM");
            String name = tables.getString("TABLE_NAME");
            String type = tables.getString("TABLE_TYPE");
            String remarks = tables.getString("REMARKS");
            dbTables.add(new DbTable(this, name, type, remarks));
        }
        Jdbcs.close(tables);
        return dbTables.toArray(new DbTable[dbTables.size()]);
    }

    private static String getConnectionSchemaName(DatabaseMetaData meta) throws SQLException {
        /*
        since 1.7
        return connection.getSchema();
        */
        String url = meta.getURL();
        String dbType = Jdbcs.getDbType(url);
        if (ORACLE.equals(dbType)) {
            return meta.getUserName();
//        } else if (POSTGRE_SQL.equals(dbType)) {
//            return "public";
        } else if (MYSQL.equals(dbType)) {
            return "";
        } else if (DERBY.equals(dbType)) {
            return meta.getUserName();
        } else if (SQL_SERVER.equals(dbType) || JTDS.equals(dbType)) {
            return "dbo";
        }
        return null;
    }


    @Override
    public String toString() {
        return name;
    }

    public DatabaseMetaData getDbMeta() {
        return dbMeta;
    }
}
